package wn.tcpip.socket.run;

import wn.tcpip.socket.netty.SocksServerInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.jms.annotation.EnableJms;

@EnableCaching
@SpringBootApplication
@EnableJms
@ComponentScan(basePackages = { "wn.tcpip"})
public class Application implements CommandLineRunner {
	static Logger logger = LogManager.getLogger();
	public static void main(String[] args) {
		ConfigurableApplicationContext content = SpringApplication.run(Application.class, args);
		
		//Test Bean
		String[]beanNames = content.getBeanDefinitionNames();
		for(String name: beanNames) {
			logger.info("beanName: {}", name);
		}
	}

	@Override
	public void run(String... strings) throws Exception {
		System.out.println(">>>>>>>>>>>>>>>start socket service<<<<<<<<<<<<<");
		try {
			EventLoopGroup bossGroup = new NioEventLoopGroup(1);
			EventLoopGroup workerGroup = new NioEventLoopGroup();
			try {
				ServerBootstrap b = new ServerBootstrap();
				b.group(bossGroup, workerGroup)
						.channel(NioServerSocketChannel.class)
						.handler(new LoggingHandler(LogLevel.INFO))
						.childHandler(new SocksServerInitializer());

				// Bind and start to accept incoming connections.
				ChannelFuture f = b.bind(10081).sync();
				// Wait until the server socket is closed.
				// In this example, this does not happen, but you can do that to gracefully
				// shut down your server.
				f.channel().closeFuture().sync();
			} finally {
				workerGroup.shutdownGracefully();
				bossGroup.shutdownGracefully();
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
